<template>
  <div class="ui-scroll-load">
    <div class="ui-scroll-load__list">
      <div
        class="ui-scroll-load__item"
        v-for="(item, index) in data"
        :key="index"
      >
        <slot name="item" :item="item"></slot>
      </div>
    </div>
    <div class="ui-scroll-load__more" v-if="data && data.length">
      <span class="ui-scroll-load__more-loading" v-if="loading"><ui-icon name="loading"></ui-icon> 数据加载中</span>
      <template v-else-if="notMore">
        <span class="ui-scroll-load__more-complete" v-if="data && data.length > pageSize">数据已加载完毕</span>
      </template>
      <span class="ui-scroll-load__more-load" v-else @click="handleLoadMoreClick">点击加载更多数据</span>
    </div>
    <template v-else>
      <template v-if="loading">
        <slot name="loading">
          <div class="ui-scroll-load__loading">
            <ui-loading></ui-loading> 数据加载中
          </div>
        </slot>
      </template>
      <div class="ui-scroll-load__empty" v-else>
        <slot name="empty">
          暂无数据
        </slot>
      </div>
    </template>
  </div>
</template>
<script>
import { getScrollParent } from '../../utils/dom'

export default {
  name: 'UiScrollLoad',
  props: {
    pageSize: {
      type: Number,
      default: 20
    },
    queryMethod: {
      type: Function
    }
  },
  data () {
    return {
      pageIndex: 0,
      loading: false,
      notMore: false,
      data: []
    }
  },
  computed: {
  },
  created () {
    this.reload()
  },
  mounted () {
    this.parentScrollEl = getScrollParent(this.$el)
    this.parentScrollEl.addEventListener('scroll', this.handleParentScroll)
  },
  methods: {
    handleParentScroll (evt) {
      if (this.loading) {
        return
      }
      if (evt.target.scrollHeight - 10 <= evt.target.scrollTop + evt.target.clientHeight) {
        this.loadMoreData()
      }
    },
    handleLoadMoreClick () {
      if (this.loading) {
        return
      }
      this.loadMoreData()
    },
    reload () {
      this.pageIndex = 0
      this.notMore = false
      this.data = []
      this.parentScrollEl && (this.parentScrollEl.scrollTop = 0)
      return this.loadData().then((data) => {
        this.data = data || []
        this.$emit('load', {
          data: this.data
        })
      })
    },
    loadMoreData () {
      if (this.notMore) {
        return Promise.reject()
      }
      this.pageIndex++
      return this.loadData().then(rs => {
        this.data = [].concat(this.data, rs)
        this.$emit('load', {
          data: this.data
        })
      })
    },
    loadData () {
      if (!this.queryMethod) {
        return Promise.reject()
      }
      this.loading = true
      const lastItem = this.data && this.data.length ? this.data[this.data.length - 1] : null
      return this.queryMethod({
        pageIndex: this.pageIndex,
        pageSize: this.pageSize
      }, lastItem).then((data) => {
        if (data.length < this.pageSize) {
          this.notMore = true
        }
        return data
      }).finally(() => {
        this.loading = false
      })
    }
  },
  beforeDestroy () {
    this.parentScrollEl && this.parentScrollEl.removeEventListener('scroll', this.handleParentScroll)
  }
}
</script>
<style lang="less">
.ui-scroll-load{

}
.ui-scroll-load__list{
  &:after {
    content: '';
    display: block;
    clear: both;
  }
}
.ui-scroll-load__item {
  box-sizing: border-box;
}
.ui-scroll-load__more{
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-bottom: 20px;
  padding-top: 12px;
  color: #999;
}
.ui-scroll-load__more-load{
  cursor: pointer;
  &:hover {
    color: #52a1e4;
  }
}
.ui-scroll-load__empty{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-top: 60px;
  height: 100%;
}
.ui-scroll-load__loading {
  text-align: center;
  color: #999;
  padding-top: 60px;
  &:after {
    content: '';
    display: block;
    clear: both;
  }
}
</style>
